package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.globalException.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.attr.AttrValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.atguigu.lease.web.admin.vo.room.RoomDetailVo;
import com.atguigu.lease.web.admin.vo.room.RoomItemVo;
import com.atguigu.lease.web.admin.vo.room.RoomQueryVo;
import com.atguigu.lease.web.admin.vo.room.RoomSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {

    @Autowired
    private RoomInfoMapper roomInfoMapper;

    @Autowired
    private ApartmentInfoMapper apartmentInfoMapper;

    @Autowired
    private GraphInfoService graphInfoService;

    @Autowired
    private RoomFacilityMapper roomFacilityMapper;
    @Autowired
    private RoomFacilityService roomFacilityService;

    @Autowired
    private RoomAttrValueMapper attrValueMapper;
    @Autowired
    private RoomAttrValueService attrValueService;

    @Autowired
    private RoomLabelMapper roomLabelMapper;
    @Autowired
    private RoomLabelService roomLabelService;

    @Autowired
    private RoomPaymentTypeMapper roomPaymentTypeMapper;
    @Autowired
    private RoomPaymentTypeService roomPaymentTypeService;


    @Autowired
    private RoomLeaseTermMapper roomLeaseTermMapper;
    @Autowired
    private RoomLeaseTermService roomLeaseTermService;

    @Autowired
    private LeaseAgreementMapper leaseAgreementMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    //根据条件分页查询房间列表
    public IPage<RoomItemVo> pageItem(Page<RoomItemVo> roomItemVoPage, RoomQueryVo queryVo) {
        return roomInfoMapper.pageItem(roomItemVoPage, queryVo);
    }

    //根据id获取房间详细信息
    public RoomDetailVo getApartmentDetail(Long id) {
        //1.根据id获取房间基本信息
        RoomInfo roomInfo = roomInfoMapper.selectById(id);

        //2.根据id获取对应公寓的基本信息
        Long apartmentId = roomInfo.getApartmentId();
        ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(apartmentId);

        //3.根据id获取房间的图片列表
        LambdaQueryWrapper<GraphInfo> grapphWrapper = new LambdaQueryWrapper<>();
        grapphWrapper.eq(GraphInfo::getItemId, id);
        grapphWrapper.eq(GraphInfo::getItemType, ItemType.ROOM);
        List<GraphInfo> graphInfoList = graphInfoService.list(grapphWrapper);
        List<GraphVo> graphVoList = new ArrayList<>();
        for (GraphInfo graphInfo : graphInfoList) {
            GraphVo graphVo = new GraphVo();
            graphVo.setName(graphInfo.getName());
            graphVo.setUrl(graphInfo.getUrl());
            graphVoList.add(graphVo);
        }

        //4.根据id和type获取房间的配套列表
        List<FacilityInfo> facilityInfoList = roomFacilityMapper.listFacilityInfoByRoomId(id);

        //5.根据id获取房间的属性列表
        List<AttrValueVo> attrValueVoList = attrValueMapper.selectByRoomId(id);

        //6.根据id获取房间的标签列表
        List<LabelInfo> labelInfoList = roomLabelMapper.listLabelInfoByRoomId(id);

        //7.根据id获取房间的支付方式列表
        List<PaymentType> paymentTypeList = roomPaymentTypeMapper.listPaymentTypeByRoomId(id);

        //8.根据id获取房间的可选租期列表
        List<LeaseTerm> leaseTermList = roomLeaseTermMapper.listLeaseTermByRoomId(id);

        //封装返回数据
        RoomDetailVo roomDetailVo = new RoomDetailVo();
        BeanUtils.copyProperties(roomInfo, roomDetailVo);
        roomDetailVo.setApartmentInfo(apartmentInfo);
        roomDetailVo.setGraphVoList(graphVoList);
        roomDetailVo.setFacilityInfoList(facilityInfoList);
        roomDetailVo.setAttrValueVoList(attrValueVoList);
        roomDetailVo.setLabelInfoList(labelInfoList);
        roomDetailVo.setPaymentTypeList(paymentTypeList);
        roomDetailVo.setLeaseTermList(leaseTermList);
        return roomDetailVo;
    }


    //保存或更新房间信息
    public void saveOrUpdateRoom(RoomSubmitVo roomSubmitVo) {
        //判断是保存还是更新
        if(roomSubmitVo.getId() != null){
            //更新

            //1.删除房间的图片列表
            LambdaQueryWrapper<GraphInfo> graphWapper = new LambdaQueryWrapper<>();
            graphWapper.eq(GraphInfo::getItemId, roomSubmitVo.getId());
            graphWapper.eq(GraphInfo::getItemType, ItemType.ROOM);
            graphInfoService.remove(graphWapper);

            //2.删除房间属性值列表
            LambdaQueryWrapper<RoomAttrValue> roomAttrValueWapper = new LambdaQueryWrapper<>();
            roomAttrValueWapper.eq(RoomAttrValue::getRoomId, roomSubmitVo.getId());
            attrValueMapper.delete(roomAttrValueWapper);

            //3.删除房间的配套列表
            LambdaQueryWrapper<RoomFacility> facilityWapper = new LambdaQueryWrapper<>();
            facilityWapper.eq(RoomFacility::getRoomId, roomSubmitVo.getId());
            roomFacilityMapper.delete(facilityWapper);

            //4.删除房间的标签列表
            LambdaQueryWrapper<RoomLabel> labelWapper = new LambdaQueryWrapper<>();
            labelWapper.eq(RoomLabel::getRoomId, roomSubmitVo.getId());
            roomLabelMapper.delete(labelWapper);

            //5.删除房间的支付方式列表
            LambdaQueryWrapper<RoomPaymentType> paymentTypeWapper = new LambdaQueryWrapper<>();
            paymentTypeWapper.eq(RoomPaymentType::getRoomId, roomSubmitVo.getId());
            roomPaymentTypeMapper.delete(paymentTypeWapper);

            //6.删除房间的可选租期列表
            LambdaQueryWrapper<RoomLeaseTerm> leaseTermWapper = new LambdaQueryWrapper<>();
            leaseTermWapper.eq(RoomLeaseTerm::getRoomId, roomSubmitVo.getId());
            roomLeaseTermMapper.delete(leaseTermWapper);

            String key = "app:room:"+roomSubmitVo.getId();
            redisTemplate.delete(key);
        }
        //再进行保存
        //1.保存房间基本信息
        super.saveOrUpdate(roomSubmitVo);
        //2.保存图片列表
        List<GraphVo> graphVoList = roomSubmitVo.getGraphVoList();
        List<GraphInfo> graphInfoList = new ArrayList<>();
        for (GraphVo graphVo : graphVoList) {
            GraphInfo graphInfo = new GraphInfo();
            graphInfo.setItemId(roomSubmitVo.getId());
            graphInfo.setItemType(ItemType.ROOM);
            graphInfo.setName(graphVo.getName());
            graphInfo.setUrl(graphVo.getUrl());
            graphInfoList.add(graphInfo);
        }
        graphInfoService.saveBatch(graphInfoList);

        //3.保存房间的属性值列表
        List<Long> attrValueIds = roomSubmitVo.getAttrValueIds();
        List<RoomAttrValue> roomAttrValueList = new ArrayList<>();
        for (Long attrValueId : attrValueIds) {
            RoomAttrValue roomAttrValue = new RoomAttrValue();
            roomAttrValue.setRoomId(roomSubmitVo.getId());
            roomAttrValue.setAttrValueId(attrValueId);
            roomAttrValueList.add(roomAttrValue);
        }
        attrValueService.saveBatch(roomAttrValueList);

        //4.保存房间的配套列表
        List<Long> facilityInfoIds = roomSubmitVo.getFacilityInfoIds();
        List<RoomFacility> roomFacilityList = new ArrayList<>();
        for (Long facilityInfoId : facilityInfoIds) {
            RoomFacility roomFacility = new RoomFacility();
            roomFacility.setRoomId(roomSubmitVo.getId());
            roomFacility.setFacilityId(facilityInfoId);
            roomFacilityList.add(roomFacility);
        }
        roomFacilityService.saveBatch(roomFacilityList);

        //5.保存房间的标签列表
        List<Long> labelInfoIds = roomSubmitVo.getLabelInfoIds();
        List<RoomLabel> roomLabelList = new ArrayList<>();
        for (Long labelInfoId : labelInfoIds) {
            RoomLabel roomLabel = new RoomLabel();
            roomLabel.setRoomId(roomSubmitVo.getId());
            roomLabel.setLabelId(labelInfoId);
            roomLabelList.add(roomLabel);
        }
        roomLabelService.saveBatch(roomLabelList);

        //6.保存房间的支付方式列表
        List<Long> paymentTypeIds = roomSubmitVo.getPaymentTypeIds();
        List<RoomPaymentType> roomPaymentTypeList = new ArrayList<>();
        for (Long paymentTypeId : paymentTypeIds) {
            RoomPaymentType roomPaymentType = new RoomPaymentType();
            roomPaymentType.setRoomId(roomSubmitVo.getId());
            roomPaymentType.setPaymentTypeId(paymentTypeId);
            roomPaymentTypeList.add(roomPaymentType);
        }
        roomPaymentTypeService.saveBatch(roomPaymentTypeList);

        //7.保存房间的可选租期列表
        List<Long> leaseTermIds = roomSubmitVo.getLeaseTermIds();
        List<RoomLeaseTerm> roomLeaseTermList = new ArrayList<>();
        for (Long leaseTermId : leaseTermIds) {
            RoomLeaseTerm roomLeaseTerm = new RoomLeaseTerm();
            roomLeaseTerm.setRoomId(roomSubmitVo.getId());
            roomLeaseTerm.setLeaseTermId(leaseTermId);
            roomLeaseTermList.add(roomLeaseTerm);
        }
        roomLeaseTermService.saveBatch(roomLeaseTermList);


    }

    //根据id修改房间状态
    public void updateReleaseStatusById(Long id, ReleaseStatus status) {
        String key = "app:room:"+id;
        redisTemplate.delete(key);
        roomInfoMapper.updateReleaseStatusById(id, status);
    }

    //根据公寓id获取房间列表
    public List<RoomInfo> listBasicByApartmentId(Long id) {
        return roomInfoMapper.listBasicByApartmentId(id);
    }

    //根据id删除房间信息
    public void removeRoomInfo(Long id) {
        //1.根据id查询是否有租约，且状态是在租中
        Integer count = leaseAgreementMapper.selectByRoomId(id);
        if(count > 0){
            throw new LeaseException(ResultCodeEnum.ADMIN_ROOM_ALREADY_LEASE);
        }
        //删除房间基本信息
        super.removeById(id);

        //2.删除房间的图片列表
        LambdaQueryWrapper<GraphInfo> graphWapper = new LambdaQueryWrapper<>();
        graphWapper.eq(GraphInfo::getItemId, id);
        graphWapper.eq(GraphInfo::getItemType, ItemType.ROOM);
        graphInfoService.remove(graphWapper);

        //3.删除房间属性值列表
        LambdaQueryWrapper<RoomAttrValue> roomAttrValueWapper = new LambdaQueryWrapper<>();
        roomAttrValueWapper.eq(RoomAttrValue::getRoomId, id);
        attrValueMapper.delete(roomAttrValueWapper);

        //4.删除房间的配套列表
        LambdaQueryWrapper<RoomFacility> facilityWapper = new LambdaQueryWrapper<>();
        facilityWapper.eq(RoomFacility::getRoomId, id);
        roomFacilityMapper.delete(facilityWapper);

        //5.删除房间的标签列表
        LambdaQueryWrapper<RoomLabel> labelWapper = new LambdaQueryWrapper<>();
        labelWapper.eq(RoomLabel::getRoomId, id);
        roomLabelMapper.delete(labelWapper);

        //6.删除房间的支付方式列表
        LambdaQueryWrapper<RoomPaymentType> paymentTypeWapper = new LambdaQueryWrapper<>();
        paymentTypeWapper.eq(RoomPaymentType::getRoomId, id);
        roomPaymentTypeMapper.delete(paymentTypeWapper);

        //7.删除房间的可选租期列表
        LambdaQueryWrapper<RoomLeaseTerm> leaseTermWapper = new LambdaQueryWrapper<>();
        leaseTermWapper.eq(RoomLeaseTerm::getRoomId, id);
        roomLeaseTermMapper.delete(leaseTermWapper);

        String key = "app:room:"+id;
        redisTemplate.delete(key);
    }
}




